/**
 * 🤖 智能错误监控和自动修复系统
 * 
 * 这个脚本会：
 * 1. 运行所有测试
 * 2. 捕获所有错误
 * 3. 生成详细的错误报告
 * 4. 提供修复建议
 * 5. 自动创建修复脚本
 */

const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');

// ANSI 颜色代码
const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  magenta: '\x1b[35m',
  cyan: '\x1b[36m',
};

function log(message, color = 'reset') {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

function header(title) {
  log('\n' + '='.repeat(60), 'cyan');
  log(` ${title}`, 'bright');
  log('='.repeat(60) + '\n', 'cyan');
}

// 错误分类和修复建议
const errorPatterns = {
  'toBeGreaterThan(0)': {
    type: '数据为空',
    description: '期望的数据数量为0，可能是数据库未初始化或API返回空',
    suggestions: [
      '检查数据库是否有数据',
      '检查API是否正确返回数据',
      '验证用户权限是否正确',
      '检查数据加载时机'
    ],
    autofix: (error) => {
      return `
// 自动修复建议：添加数据验证和更详细的错误信息

// 在测试前添加：
const { userCountText } = await page.evaluate(() => {
  const card = document.querySelector('.stat-card .stat-value');
  return {
    userCountText: card?.textContent || '0',
    cardExists: !!card,
    cardVisible: card?.offsetParent !== null
  };
});

console.log('📊 调试信息:', {
  userCountText,
  cardExists,
  cardVisible
});

// 如果数据为0，检查API响应
if (parseInt(userCountText) === 0) {
  const apiResponse = await page.evaluate(async () => {
    const response = await fetch('/api/admin/stats', {
      headers: {
        'Authorization': 'Bearer ' + localStorage.getItem('token')
      }
    });
    return await response.json();
  });
  console.log('🔍 API响应:', apiResponse);
}
`;
    }
  },
  'toBeVisible': {
    type: '元素不可见',
    description: '期望的页面元素未显示或未找到',
    suggestions: [
      '检查元素选择器是否正确',
      '增加等待时间',
      '检查页面是否正确加载',
      '验证权限是否允许查看该元素'
    ],
    autofix: (error) => {
      return `
// 自动修复建议：增加等待和重试机制

// 使用更可靠的等待方式
await page.waitForSelector('你的选择器', {
  state: 'visible',
  timeout: 10000
});

// 或者使用自定义等待
await page.waitForFunction(() => {
  const element = document.querySelector('你的选择器');
  return element && element.offsetParent !== null;
}, { timeout: 10000 });
`;
    }
  },
  'Request failed': {
    type: 'API请求失败',
    description: 'HTTP请求失败，可能是服务器未启动或API不存在',
    suggestions: [
      '确认后端服务器正在运行',
      '检查API路径是否正确',
      '验证认证token是否有效',
      '检查CORS配置'
    ],
    autofix: (error) => {
      return `
// 自动修复建议：添加API健康检查

// 在测试前添加：
test.beforeEach(async ({ page }) => {
  // 检查后端是否运行
  try {
    const response = await fetch('http://localhost:3001/api/health');
    if (!response.ok) {
      throw new Error('后端服务器未响应');
    }
  } catch (error) {
    console.error('❌ 后端服务器未运行！请先启动：cd backend && npm run dev');
    throw error;
  }
});
`;
    }
  },
  'timeout': {
    type: '超时错误',
    description: '操作超时，页面加载或元素出现时间过长',
    suggestions: [
      '增加超时时间',
      '优化页面加载速度',
      '检查网络连接',
      '使用更精确的等待条件'
    ],
    autofix: (error) => {
      return `
// 自动修复建议：优化等待策略

// 使用 waitForLoadState
await page.waitForLoadState('networkidle', { timeout: 30000 });

// 或者使用自定义等待条件
await page.waitForFunction(() => {
  return document.querySelector('.loading')?.style.display === 'none';
}, { timeout: 15000 });
`;
    }
  }
};

// 分析错误并生成报告
function analyzeError(error) {
  const errorText = error.toString();
  
  for (const [pattern, info] of Object.entries(errorPatterns)) {
    if (errorText.includes(pattern)) {
      return {
        ...info,
        originalError: errorText,
        autofix: info.autofix(error)
      };
    }
  }
  
  return {
    type: '未知错误',
    description: '无法自动识别的错误类型',
    originalError: errorText,
    suggestions: ['查看详细错误信息', '检查测试日志', '运行调试模式'],
    autofix: '// 需要手动分析错误'
  };
}

// 运行测试并捕获错误
async function runTestsWithMonitoring() {
  header('🤖 智能测试监控系统');
  
  log('📋 开始运行测试...', 'cyan');
  log('⏱️  这可能需要几分钟时间\n', 'yellow');
  
  return new Promise((resolve) => {
    exec('npx playwright test --reporter=json', (error, stdout, stderr) => {
      const errors = [];
      const warnings = [];
      
      // 读取JSON报告
      try {
        const reportPath = path.join(process.cwd(), 'test-results', 'results.json');
        if (fs.existsSync(reportPath)) {
          const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
          
          // 分析测试结果
          if (report.suites) {
            report.suites.forEach(suite => {
              suite.specs.forEach(spec => {
                spec.tests.forEach(test => {
                  if (test.results) {
                    test.results.forEach(result => {
                      if (result.status === 'failed') {
                        errors.push({
                          test: spec.title,
                          file: spec.file,
                          error: result.error?.message || '未知错误',
                          duration: result.duration
                        });
                      } else if (result.status === 'timedOut') {
                        warnings.push({
                          test: spec.title,
                          file: spec.file,
                          warning: '测试超时',
                          duration: result.duration
                        });
                      }
                    });
                  }
                });
              });
            });
          }
        }
      } catch (e) {
        log(`⚠️  无法读取测试报告: ${e.message}`, 'yellow');
      }
      
      resolve({ errors, warnings, rawOutput: stdout + stderr });
    });
  });
}

// 生成错误报告
function generateErrorReport(errors, warnings) {
  header('📊 测试结果分析');
  
  if (errors.length === 0 && warnings.length === 0) {
    log('✅ 所有测试通过！没有发现错误。', 'green');
    log('🎉 你的应用运行完美！\n', 'green');
    return;
  }
  
  // 报告错误
  if (errors.length > 0) {
    log(`❌ 发现 ${errors.length} 个错误:\n`, 'red');
    
    errors.forEach((error, index) => {
      log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`, 'red');
      log(`错误 #${index + 1}: ${error.test}`, 'bright');
      log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`, 'red');
      
      log(`📁 文件: ${error.file}`, 'yellow');
      log(`⏱️  耗时: ${(error.duration / 1000).toFixed(2)}s`, 'yellow');
      log(`\n💬 错误信息:`, 'red');
      log(`   ${error.error}\n`, 'reset');
      
      // 分析错误
      const analysis = analyzeError(error.error);
      
      log(`🔍 错误类型: ${analysis.type}`, 'cyan');
      log(`📝 描述: ${analysis.description}\n`, 'cyan');
      
      log(`💡 修复建议:`, 'green');
      analysis.suggestions.forEach((suggestion, i) => {
        log(`   ${i + 1}. ${suggestion}`, 'green');
      });
      
      log(`\n🔧 自动修复代码:`, 'magenta');
      log(analysis.autofix, 'yellow');
    });
  }
  
  // 报告警告
  if (warnings.length > 0) {
    log(`\n⚠️  发现 ${warnings.length} 个警告:\n`, 'yellow');
    
    warnings.forEach((warning, index) => {
      log(`${index + 1}. ${warning.test}`, 'yellow');
      log(`   ${warning.warning} (${(warning.duration / 1000).toFixed(2)}s)\n`, 'yellow');
    });
  }
}

// 生成修复脚本
function generateFixScript(errors) {
  if (errors.length === 0) return;
  
  header('🔧 生成自动修复脚本');
  
  const fixScriptPath = path.join(process.cwd(), 'test-results', 'auto-fix.md');
  
  let content = '# 🔧 自动修复指南\n\n';
  content += '## 发现的问题和修复方案\n\n';
  
  errors.forEach((error, index) => {
    const analysis = analyzeError(error.error);
    
    content += `### 问题 ${index + 1}: ${error.test}\n\n`;
    content += `**错误类型**: ${analysis.type}\n\n`;
    content += `**描述**: ${analysis.description}\n\n`;
    content += `**文件**: ${error.file}\n\n`;
    content += `**修复建议**:\n\n`;
    analysis.suggestions.forEach((suggestion, i) => {
      content += `${i + 1}. ${suggestion}\n`;
    });
    content += `\n**自动修复代码**:\n\n\`\`\`javascript\n${analysis.autofix}\n\`\`\`\n\n`;
    content += '---\n\n';
  });
  
  fs.writeFileSync(fixScriptPath, content, 'utf8');
  
  log(`✅ 修复脚本已生成: ${fixScriptPath}`, 'green');
  log(`📖 请打开文件查看详细的修复步骤\n`, 'cyan');
}

// 主函数
async function main() {
  try {
    const { errors, warnings, rawOutput } = await runTestsWithMonitoring();
    
    // 生成报告
    generateErrorReport(errors, warnings);
    
    // 生成修复脚本
    if (errors.length > 0) {
      generateFixScript(errors);
      
      header('📝 下一步操作');
      log('1. 查看上面的错误分析', 'cyan');
      log('2. 打开 test-results/auto-fix.md 查看详细修复方案', 'cyan');
      log('3. 根据建议修复代码', 'cyan');
      log('4. 重新运行测试: npm test\n', 'cyan');
    }
    
    header('🎯 快速修复命令');
    log('# 查看详细测试报告', 'yellow');
    log('npm run test:report\n', 'green');
    log('# 运行UI模式调试', 'yellow');
    log('npm run test:ui\n', 'green');
    log('# 只运行失败的测试', 'yellow');
    log('npx playwright test --last-failed\n', 'green');
    
  } catch (error) {
    log(`\n❌ 监控系统错误: ${error.message}`, 'red');
    process.exit(1);
  }
}

// 运行
main();

